﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;

namespace API.Core.ActionFilters
{
    /*
    public class CustomErrorAttribute : System.Web.Mvc.HandleErrorAttribute
    {
        public override void OnException(System.Web.Mvc.ExceptionContext filterContext)
        {
            if (filterContext.Exception != null)
            {
                filterContext.Result = new 
                filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.InternalServerError,
                    new CommonResponse(filterContext.Exception)
                    {
                        RequestParameters = RequestParameters
                    });

                return;
            }
        }
    }
    */

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class CustomQueryableAttribute : QueryableAttribute
    {
        public override void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext)
        {
            var RequestParameters = new Dictionary<string, string>();
            var ParsedQueryString = actionExecutedContext.Request.RequestUri.ParseQueryString();

            foreach (string param in ParsedQueryString)
            {
                RequestParameters.Add(param, ParsedQueryString[param]);
            }

            if (actionExecutedContext.Exception != null)
            {
                actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.InternalServerError,
                    new CommonResponse(actionExecutedContext.Exception)
                    {
                        RequestParameters = RequestParameters
                    });

                return;
            }

            long originalsize = 0;

            var inlinecount = System.Web.HttpUtility.ParseQueryString(actionExecutedContext.Request.RequestUri.Query).Get("$inlinecount");
            var isAudit = System.Web.HttpUtility.ParseQueryString(actionExecutedContext.Request.RequestUri.Query).Get("$audit");

            object responseObject;
            actionExecutedContext.Response.TryGetContentValue(out responseObject);
            var originalquery = responseObject as IQueryable<object>;

            if (originalquery != null)
            {
                originalsize = originalquery.Count();
            }

            base.OnActionExecuted(actionExecutedContext);

            if (ResponseIsValid(actionExecutedContext.Response))
            {
                actionExecutedContext.Response.TryGetContentValue(out responseObject);

                if (responseObject is IQueryable)
                {
                    var robj = responseObject as IQueryable<object>;

                    actionExecutedContext.Response = actionExecutedContext.Request.CreateResponse(HttpStatusCode.OK,
                        new CommonResponse(robj)
                        {
                            RequestParameters = RequestParameters,
                            TotalCount = originalsize,
                            SqlStatement = (isAudit == Boolean.TrueString) ? robj.ToString() : null
                        });
                }
            }
        }

        public override void ValidateQuery(HttpRequestMessage request)
        {
            //everything is allowed
        }

        private bool ResponseIsValid(HttpResponseMessage response)
        {
            if (response == null || response.StatusCode != HttpStatusCode.OK || !(response.Content is ObjectContent)) return false;
            return true;
        }
    }
}